/*
 *    Webical - http://www.webical.org
 *    Copyright (C) 2007 Func. Internet Integration
 *
 *    This file is part of Webical.
 *
 *    $Id: EventForm.java 382 2013-03-03 14:56:50Z hz0885@gmail.com $
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.webical.web.component.event;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.extensions.markup.html.form.DateTextField;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.RequiredTextField;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.StringResourceModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.webical.Calendar;
import org.webical.Event;
import org.webical.User;
import org.webical.ical.Recurrence;
import org.webical.ical.RecurrenceUtil;
import org.webical.manager.CalendarManager;
import org.webical.manager.WebicalException;
import org.webical.util.CalendarUtils;
import org.webical.web.action.IAction;
import org.webical.web.action.ShowCalendarAction;
import org.webical.web.action.StoreEventAction;
import org.webical.web.action.RemoveEventAction;
import org.webical.web.app.WebicalSession;
import org.webical.web.app.WebicalWebAplicationException;

/**
 * The form used for adding and editing events. This class has two abstract methods
 * that have to be implemented by the panel to handle the persist and discard actions
 * generated by the form.
 *
 * @author Mattijs Hoitink
 *
 */
public abstract class EventForm extends Form {

	private static final long serialVersionUID = 0L;
	private static Log log = LogFactory.getLog(EventFormPanel.class);

	// markup ID's
	private static final String HEADING_LABEL_MARKUP_ID 				= "headingLabel";
	private static final String FORM_FEEDBACK_MARKUP_ID 				= "formFeedback";

	private static final String EVENT_SUMMARY_TEXTFIELD_MARKUP_ID 		= "summary";
	private static final String EVENT_START_DATE_TEXTFIELD_MARKUP_ID 	= "dtStart";
	private static final String EVENT_END_DATE_TEXTFIELD_MARKUP_ID 		= "dtEnd";
	private static final String EVENT_START_TIME_TEXTFIELD_MARKUP_ID 	= "tmStart";
	private static final String EVENT_END_TIME_TEXTFIELD_MARKUP_ID 		= "tmEnd";
	private static final String EVENT_LOCATION_TEXTFIELD_MARKUP_ID 		= "location";
	private static final String EVENT_CALENDAT_DROPDOWN_MARKUP_ID 		= "calendar";
	private static final String EVENT_DESCRIPTION_TEXTAREA_MARKUP_ID 	= "description";
	private static final String REPEAT_FREQUENCY_DROPDOWN_MARKUP_ID 	= "frequency";
	private static final String CLEAR_FREQUENCY_BUTTON_MARKUP_ID 		= "clearFrequencyButton";
	private static final String REPEAT_INTERVAL_TEXTFIELD_MARKUP_ID 	= "interval";
	private static final String REPEAT_COUNT_TEXTFIELD_MARKUP_ID 		= "count";
	private static final String REPEAT_UNTIL_TEXTFIELD_MARKUP_ID 		= "until";
	private static final String REPEAT_UNTIL_FORMAT_LABEL_MARKUP_ID 	= "untilFormat";

	private static final String ALLDAY_BUTTON_MARKUP_ID 				= "alldayButton";
	private static final String DISCARD_BUTTON_MARKUP_ID 				= "discardButton";
	private static final String SUBMIT_BUTTON_MARKUP_ID 				= "submitButton";

	// Resource ID's
	private static final String ADD_EVENT_HEADING_RESOURCE_ID			= "add.heading";
	private static final String EDIT_EVENT_HEADING_RESOURCE_ID			= "edit.heading";
	private static final String ALLDAY_BUTTON_RESOURCE_ID 				= "alldayButton.text";
	private static final String CLEAR_FREQUENCY_BUTTON_RESOURCE_ID 		= "clearFrequencyButton.text";
	private static final String ADD_BUTTON_RESOURCE_ID 					= "add.button";
	private static final String EDIT_BUTTON_RESOURCE_ID 				= "edit.button";

	// form elements
	private Button allDayButton, clearRecurrenceButton, submitButton, discardButton;
	private DateTextField startDateTextField, startTimeTextField, endDateTextField, endTimeTextField;
	private DropDownChoice calendarDropDownChoice, repeatFrequencyDropDownChoice;
	private FeedbackPanel formFeedback;
	private Label headingLabel, untilFormatLabel;
	private RequiredTextField summaryTextField;
	private TextField locationTextField, repeatIntervalTextField, repeatCountTextField, repeatUntilTextField;
	private TextArea descriptionTextArea;

	/**
	 * Used by Spring to set the Calendar Manager
	 */
	@SpringBean(name="calendarManager")
	private CalendarManager calendarManager;

	/**
	 * The Event for this form
	 */
	private Event formEvent;

	/**
	 * The event wrapper for the Event
	 */
	private EventWrapper eventWrapper;

	/**
	 * A deep copy of the event to exclude it from the range if necessary
	 */
	private Event oldEvent;

	/**
	 * The date the selected event is on, or the date the new event should be on
	 */
	private GregorianCalendar selectedDate;

	/**
	 * Whether this is an edit form or not
	 */
	private boolean editForm;

	//TODO It isn't clear if this option is used, what it does and what it should do. This has to be clear before it can be implemented
	// Add it to the EventWrapper? or to the user settings?
	//True: show events with user offset
	//False: show events in ics dtstart, so calendar offset
	private boolean overruleCalendarTimeZone = false;
	private Long offSetUser = new Long(1);

	private SimpleDateFormat dateFormat, timeFormat;

	/**
	 * Constructor
	 * @param id the markup id
	 * @param editEvent the {@link Event} to be edited, null for a new Event
	 * @param selectedDate The date the selected event is on, or the date the new event should be on
	 *
	 */
	public EventForm(String id, Event event, GregorianCalendar selectedDate) {
		super(id);
		this.formEvent = event;
		this.selectedDate = selectedDate;

		// Check if we are editing an event
		if(formEvent != null) {
			// Clone the event and keep it for later reference
			try {
				this.oldEvent = (Event) BeanUtils.cloneBean(formEvent);
			} catch (Exception e) {
				log.error("could not clone event: " + formEvent.getUid(), e);
				throw new WebicalWebAplicationException(e);
			}

			// Create a new empty ExtendedEvent
			this.eventWrapper = new EventWrapper(formEvent);
			this.editForm = true;

			// Check if the event is recurring
			/* Disabled for milestone 0.4
			 if(RecurrenceUtil.isRecurrent(eventWrapper.getEvent())) {
				// Override the event start and end date to the date the selected event instance is on
				eventWrapper.setEventStartDate(selectedDate.getTime());
				eventWrapper.setEventEndDate(selectedDate.getTime());
			}*/

			// XXX mattijs: leave this comment here until extensive testing has been done
			/*if(eventWrapper.getrRule().size() != 0){

				Recurrence recurrence = null;
				try {
					recurrence = RecurrenceUtil.getRecurrenceFromRecurrenceRuleSet(eventWrapper.getrRule());
				} catch (WebicalException e) {
					throw new WebicalWebAplicationException(e);
				}
				if(recurrence != null && recurrence.getFrequency() > 0 && recurrence.getInterval() != -1){

					int frequency = recurrence.getFrequency();

					RecurrenceFrequentyStringResourceModel myStringResourceModel = RecurrenceFrequentyStringResourceModel.getStringResourceModel(frequency, frequencyModels);
					if(myStringResourceModel != null){
						eventWrapper.setFrequency(myStringResourceModel);
					}

					eventWrapper.setInterval(new Integer(recurrence.getInterval()));

					if(recurrence.getCount() != -1){
						eventWrapper.setCount(new Integer(recurrence.getCount()));
					}
					if(recurrence.getEndDay() != null){
						eventWrapper.setUntil(recurrence.getEndDay());
					}
				}
			}*/

		} else {
			// create a new event
			this.editForm = false;
			createEmptyEvent();
		}

		// Set up the Form
		createFormElements();
		if (this.editForm) {
			alterFormForEditing();
		}
		addFormElements();
	}

	/**
	 * Create the form elements
	 */
	private void createFormElements() {
		// Heading
		headingLabel = new Label(HEADING_LABEL_MARKUP_ID, new StringResourceModel(ADD_EVENT_HEADING_RESOURCE_ID, EventForm.this, new Model("Add event")));
		// Feedback Panel
		formFeedback = new FeedbackPanel(FORM_FEEDBACK_MARKUP_ID);
		//Title
		summaryTextField = new RequiredTextField(EVENT_SUMMARY_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "summary"));

		dateFormat = new SimpleDateFormat(WebicalSession.getWebicalSession().getUserSettings().getDateFormat(), getLocale());
		timeFormat = new SimpleDateFormat(WebicalSession.getWebicalSession().getUserSettings().getTimeFormat(), getLocale());

		// Event Start fields
		startDateTextField = new DateTextField(EVENT_START_DATE_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "eventStartDate"), dateFormat.toLocalizedPattern());
		startDateTextField.setRequired(true);
		startTimeTextField = new DateTextField(EVENT_START_TIME_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "eventStartTime"), timeFormat.toLocalizedPattern());
		startTimeTextField.setRequired(true);

		// Event End fields
		endDateTextField = (DateTextField) new DateTextField(EVENT_END_DATE_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "eventEndDate"), dateFormat.toLocalizedPattern()).setRequired(true);
		endTimeTextField = (DateTextField) new DateTextField(EVENT_END_TIME_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "eventEndTime"), timeFormat.toLocalizedPattern());
		endTimeTextField.setRequired(true);

		// All Day Button
		allDayButton = new Button(ALLDAY_BUTTON_MARKUP_ID, new StringResourceModel(ALLDAY_BUTTON_RESOURCE_ID, EventForm.this, new Model("All day"))) {
			private static final long serialVersionUID = 1L;

			/*(non-Javadoc)
			 * @see org.apache.wicket.markup.html.form.Button#onSubmit()
			 */
			@Override
			public void onSubmit() {
				if (eventWrapper.isAllDay()) {
					setNormalDayEventFields();
				} else {
					setAllDayEventFields();
				}
			}
		};
		allDayButton.setDefaultFormProcessing(false);

		// Location
		locationTextField = new TextField(EVENT_LOCATION_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "location"));
		// Calendar
		List<Calendar> availableCalendars = getAvailableCalendars(WebicalSession.getWebicalSession().getUser());
		calendarDropDownChoice = (DropDownChoice) new DropDownChoice(EVENT_CALENDAT_DROPDOWN_MARKUP_ID, new PropertyModel(eventWrapper, "calendar"), availableCalendars).setRequired(true);
		if (availableCalendars.size() > 0) {
			if (! editForm) eventWrapper.setCalendar(availableCalendars.get(0));
		}
		// Description
		descriptionTextArea = new TextArea(EVENT_DESCRIPTION_TEXTAREA_MARKUP_ID, new PropertyModel(eventWrapper, "description"));

		// Frequency
		final List<Integer> recurrenceOptions = Arrays.asList(new Integer[] { 0, Recurrence.DAILY, Recurrence.WEEKLY, Recurrence.MONTHLY, Recurrence.YEARLY });
		repeatFrequencyDropDownChoice = new DropDownChoice(REPEAT_FREQUENCY_DROPDOWN_MARKUP_ID, new PropertyModel(eventWrapper, "frequency"), recurrenceOptions, new IChoiceRenderer() {
			private static final long serialVersionUID = 1L;

			public Object getDisplayValue(Object object) {
				String recurrenceString = "";
                int value = ((Integer)object).intValue();
                switch (value)
                {
                    case Recurrence.DAILY :
                    	recurrenceString = new StringResourceModel("recur.daily", EventForm.this, null).getString();
                        break;
                    case Recurrence.WEEKLY :
                    	recurrenceString = new StringResourceModel("recur.weekly", EventForm.this, null).getString();
                        break;
                    case Recurrence.MONTHLY :
                    	recurrenceString = new StringResourceModel("recur.monthly", EventForm.this, null).getString();
                        break;
                    case Recurrence.YEARLY:
                    	recurrenceString = new StringResourceModel("recur.yearly", EventForm.this, null).getString();
					   	break;
                    case 0:
                    	recurrenceString = new StringResourceModel("recur.none", EventForm.this, null).getString();
                    	break;
					default:
						recurrenceString = new StringResourceModel("recur.none", EventForm.this, null).getString();
						break;
                }
                return recurrenceString;
			}

			public String getIdValue(Object object, int index) {
				if (index >= 0) {
					return String.valueOf((index));
				}
				return null;
			}
		});
		if (!editForm || eventWrapper.getFrequency() == null) {
			eventWrapper.setFrequency(0);
		}

		// Clear frequency button
		clearRecurrenceButton = new Button(CLEAR_FREQUENCY_BUTTON_MARKUP_ID, new StringResourceModel(CLEAR_FREQUENCY_BUTTON_RESOURCE_ID, EventForm.this, new Model("Clear"))) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSubmit() {
				// Reset the recurrence
				eventWrapper.setFrequency(0);
				repeatFrequencyDropDownChoice.modelChanged();
				eventWrapper.setInterval(null);
				repeatIntervalTextField.modelChanged();
				eventWrapper.setCount(null);
				repeatCountTextField.modelChanged();
				eventWrapper.setUntil(null);
				repeatUntilTextField.modelChanged();

				super.onSubmit();
			}
		};
		clearRecurrenceButton.setDefaultFormProcessing(false);

		// Interval
		repeatIntervalTextField = new TextField(REPEAT_INTERVAL_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "interval"), Integer.class);
		// Count
		repeatCountTextField = new TextField(REPEAT_COUNT_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "count"), Integer.class);
		// Until
		repeatUntilTextField = new DateTextField(REPEAT_UNTIL_TEXTFIELD_MARKUP_ID, new PropertyModel(eventWrapper, "until"), WebicalSession.getWebicalSession().getUserSettings().getDateFormat());
		untilFormatLabel = new Label(REPEAT_UNTIL_FORMAT_LABEL_MARKUP_ID, WebicalSession.getWebicalSession().getUserSettings().getDateFormat());

		discardButton = new Button(DISCARD_BUTTON_MARKUP_ID) {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSubmit() {
				EventForm.this.onAction(new ShowCalendarAction());
			}
		};
		discardButton.setDefaultFormProcessing(false);

		// Submit Button
		submitButton = new Button(SUBMIT_BUTTON_MARKUP_ID, new StringResourceModel(ADD_BUTTON_RESOURCE_ID, EventForm.this, new Model("Add")));
	}

	/**
	 * Alters the form elements for rendering an edit form
	 */
	private void alterFormForEditing() {
		// Change the form header
		headingLabel.setModel(new StringResourceModel(EDIT_EVENT_HEADING_RESOURCE_ID, EventForm.this, new Model("Edit event")));
		// Change the submit button text
		submitButton.setModel(new StringResourceModel(EDIT_BUTTON_RESOURCE_ID, EventForm.this, new Model("Edit")));
		// set the correct calendar for the drop down choice
		calendarDropDownChoice.setModel(new PropertyModel(eventWrapper, "calendar"));
		if (this.eventWrapper.isAllDay()) {
			setAllDayEventFields();
		}
	}

	/**
	 * Add the form elements to the form
	 */
	private void addFormElements() {
		addOrReplace(headingLabel);
		addOrReplace(formFeedback);
		addOrReplace(summaryTextField);
		addOrReplace(startTimeTextField);
		addOrReplace(startDateTextField);
		addOrReplace(endTimeTextField);
		addOrReplace(endDateTextField);
		addOrReplace(allDayButton);
		addOrReplace(calendarDropDownChoice);
		addOrReplace(locationTextField);
		addOrReplace(descriptionTextArea);
		addOrReplace(repeatFrequencyDropDownChoice);
		addOrReplace(clearRecurrenceButton);
		addOrReplace(repeatIntervalTextField);
		addOrReplace(repeatCountTextField);
		addOrReplace(repeatUntilTextField);
		addOrReplace(untilFormatLabel);
		addOrReplace(discardButton);
		addOrReplace(submitButton);
	}

	/**
	 * Create an empty Event and set the start and end times
	 * @return Event
	 */
	private EventWrapper createEmptyEvent() {
		this.formEvent = new Event();
		this.eventWrapper = new EventWrapper(formEvent);

		GregorianCalendar dateCalendar = CalendarUtils.duplicateCalendar(selectedDate);
		GregorianCalendar timeCalendar = CalendarUtils.newTodayCalendar(dateCalendar.getFirstDayOfWeek());
		dateCalendar.set(GregorianCalendar.HOUR_OF_DAY, timeCalendar.get(GregorianCalendar.HOUR_OF_DAY));
		dateCalendar.set(GregorianCalendar.MINUTE, timeCalendar.get(GregorianCalendar.MINUTE) / 5 * 5);

		//Fill the start and end times with proper values
		eventWrapper.setDtStart(dateCalendar.getTime());
		dateCalendar.add(GregorianCalendar.HOUR_OF_DAY, 1);
		eventWrapper.setDtEnd(dateCalendar.getTime());

		return this.eventWrapper;
	}

	/**
	 * Update the form and event for an all day event
	 */
	public void setAllDayEventFields() {
		eventWrapper.setAllDay();

		// Replace the DateTextField
		replaceFormDateComponents(true);
	}

	/**
	 * Update the form and event for a non all day event
	 */
	public void setNormalDayEventFields() {
		eventWrapper.resetAllDay();

		// Replace the DateTextFields
		replaceFormDateComponents(false);
	}

	/**
	 * Replace the DateTextFields on the form, and update the allDay button
	 * @param allDay wheter the form is used for an all day event
	 */
	public void replaceFormDateComponents(boolean allDay) {
		if (allDay) {
			allDayButton.setModel(new StringResourceModel("AllDay_label_False", this, null));
			startTimeTextField.setEnabled(false);
			startTimeTextField.setVisible(false);
			endTimeTextField.setEnabled(false);
			endTimeTextField.setVisible(false);
		} else {
			allDayButton.setModel(new StringResourceModel("AllDay_label_True", this, null));
			startTimeTextField.setEnabled(true);
			startTimeTextField.setVisible(true);
			endTimeTextField.setEnabled(true);
			endTimeTextField.setVisible(true);
		}

		addOrReplace(startTimeTextField);
		addOrReplace(endTimeTextField);
	}

	/**
	 * Show confirmation panel when editing a recurring event 
	 */
	@SuppressWarnings("unused")
	private void showConfirmation() {
		final EventFormPanel parent = (EventFormPanel) EventForm.this.getParent();
		parent.replaceWith(new ConfirmRecurringActionPanel(parent.getId(), "Which instances of " + formEvent.getSummary() + " do you want to alter?") {
			private static final long serialVersionUID = 1L;

			@Override
			public void onCancel() {
				this.replaceWith(parent);
			}

			@Override
			public void onConfirmThis() {
				EventForm.this.alterThisEventInstance();
			}

			@Override
			public void onConfirmAll() {
				// Update all the event instances
				EventForm.this.alterAllEventInstances();
			}

			@Override
			public void onConfirmFollowing() {
				EventForm.this.alterFollowingEventInstances();
			}
		});
	}

	/**
	 * Stores a new event and excludes it from the old range.
	 */
	private void alterThisEventInstance() {
		// Exclude the new event from the recurrence rule
		RecurrenceUtil.excludeEventFromRecurrenceRule(eventWrapper.getEvent(), oldEvent, true);

		// set the UID from the new event to null so it will be saved as a new event
		eventWrapper.getEvent().setUid(null);

		// set the eventId to null so hibernate won't override the old event
		eventWrapper.getEvent().setEventId(null);

		// Store the events
		EventForm.this.onAction(new StoreEventAction(Arrays.asList(new Event[] {oldEvent, eventWrapper.getEvent()})));
	}

	private void alterFollowingEventInstances() {
		log.info("Altering following instance only");
	}

	/**
	 * Get a list of calendars accessible to this user
	 * @param user the User
	 * @return List<Calendar> the list with user calendars
	 */
	private List<Calendar> getAvailableCalendars(User user) {
		List<Calendar> availableCalendars = new ArrayList<Calendar>();
		try {
			List<Calendar> userCalendars = calendarManager.getCalendars(user);
			if (userCalendars != null) {
				Iterator<Calendar> calIt = userCalendars.iterator();
				while (calIt.hasNext())
				{
					Calendar calendar = calIt.next();
					if (! calendar.getReadOnly()) availableCalendars.add(calendar);
				}
			}
		} catch (WebicalException we) {
			log.error("getAvailableCalendars:Retrieving User Calendars", we);
		}
		return availableCalendars;
	}

	/* (non-Javadoc)
	 * @see org.apache.wicket.markup.html.form.Form#onSubmit()
	 */
	@Override
	public void onSubmit() {
		// Do some checks to see if the dates are filled in correct
		if(eventWrapper.getDtEnd().before(eventWrapper.getDtStart())) {
			error(new StringResourceModel("Exception.endbeforestart", this, null).getString());
		}
		else if(!eventWrapper.isAllDay() && eventWrapper.getDtEnd().equals(eventWrapper.getDtStart())) {
			error(new StringResourceModel("Exception.endbeforestart", this, null).getString());
		}
		else if (findSubmittingButton().equals(submitButton)) {
			// Check if we are editing a recurring event
			if (editForm && RecurrenceUtil.isRecurrent(eventWrapper.getEvent())) {
				// Editing specific events in a recurrence rule is disabled for milestone 0.4
				//showConfirmation();
				alterAllEventInstances();
			} else {
				// Store the event as normal
				alterAllEventInstances();
			}
		}
	}

	/**
	 * Stores all the event instances
	 */
	private void alterAllEventInstances() {
		if (overruleCalendarTimeZone && !eventWrapper.getEvent().isAllDay()) {
			//Display dtstart and dtend in user timezone
			Integer offSetCalendar = eventWrapper.getEvent().getCalendar().getOffSetFrom();

			if (offSetCalendar != null) {
				float difference = offSetUser.floatValue() - offSetCalendar.floatValue();
				if (eventWrapper.getEvent().getDtStart() != null) {
					eventWrapper.getEvent().setDtStart(CalendarUtils.addHours(eventWrapper.getEvent().getDtStart(), - difference));
				}
				if (eventWrapper.getEvent().getDtEnd() != null) {
					eventWrapper.getEvent().setDtEnd(CalendarUtils.addHours(eventWrapper.getEvent().getDtEnd(), - difference));
				}
			}
		}

		eventWrapper.storeRecurrence();

		/*if(eventWrapper.getFrequency() != null && eventWrapper.getInterval() != null) {
			if(eventWrapper.getCount() == null){
				RecurrenceUtil.setRecurrenceRule(storeEvent, new Recurrence(eventWrapper.getFrequency(), eventWrapper.getInterval(), eventWrapper.getUntil()));
			} else {
				RecurrenceUtil.setRecurrenceRule(storeEvent, new Recurrence(eventWrapper.getFrequency(), eventWrapper.getCount(), eventWrapper.getInterval(), eventWrapper.getUntil()));
			}
		} else {
			//Clear the recurrence
			RecurrenceUtil.clearRecurrence(storeEvent);
		}*/

		//Refresh the event calendar, or else there is a lazilyexception
		/*Calendar storeCalendar;
		try {
			storeCalendar = calendarManager.getCalendarForEvent(storeEvent);
		} catch (WebicalException e1) {
			 throw new WebicalWebAplicationException(e1);
		}*/

		//Save the event
		/*
		try {
			//If the is a gCalendar than put this remove this event from its series
			if (excludeFromRange) {
				oldEvent.getExDate().add(date.getTime());
				eventManager.storeEvent(oldEvent);
			}
			eventManager.storeEvent(storeEvent);

			if (log.isDebugEnabled()) {
				log.debug("Event saved: " + storeEvent.getSummary() + " for calendar: " + storeEvent.getCalendar().getName());
			}

			//Change back to the list
			EventAddEditPanel.this.onAction(new FormFinishedAction(null));
		} catch (WebicalException e) {
			if (e.getCause().getClass() == UpdateConflictException.class) {
				if (log.isDebugEnabled()) {
					log.debug("update exception");
				}
				eventSelectionListener.eventUpdateandDeleteException(storeEvent, storeCalendar, true);
			} else if (e.getCause().getClass() == DeleteConflictException.class) {
				if (log.isDebugEnabled()) {
					log.debug("delete exception");
				}
				eventSelectionListener.eventUpdateandDeleteException(storeEvent, storeCalendar, false);
			} else {
				error("Could not store the event");
				throw new WebicalWebAplicationException("Event could not be saved: " + storeEvent.getSummary(), e);
			}
		}
		*/
		// Store the event
		if (editForm  &&
			oldEvent.getCalendar().getCalendarId() != eventWrapper.getCalendar().getCalendarId())
		{
			log.info("Change Event Calendar " + eventWrapper.getCalendar().getName());
			EventForm.this.onAction(new RemoveEventAction(oldEvent));
			eventWrapper.setEventId(null);
			eventWrapper.setUid(null);
			EventForm.this.onAction(new StoreEventAction(eventWrapper.getEvent()));
		}
		else
		{
			EventForm.this.onAction(new StoreEventAction(eventWrapper.getEvent()));
		}
	}

	/**
	 * Handles actions generated by this form
	 * @param action The action to handle
	 */
	public abstract void onAction(IAction action);
}
